package com.msmall.community.user.model;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import com.msmall.base.model.BaseObject;
import com.msmall.base.util.ConstantDB;
import com.msmall.base.util.DateUtil;
import com.msmall.community.ApplicationManager;
import com.msmall.community.convene.model.Convene;
import com.msmall.community.money.model.Money;
import com.msmall.community.money.model.MoneyTransaction;
import com.msmall.community.mood.model.Mood;
import com.msmall.community.mood.service.MoodManager;
import com.msmall.community.play.cases.model.UserCases;
import com.msmall.community.score.model.Score;
import com.msmall.community.score.model.ScoreTransaction;

@Entity
@Table(name="base_user_info")
public class UserInfo extends BaseObject {

	private static final long serialVersionUID = -855076845559928199L;

	@Id
	@Column(name="user_id",insertable=false,updatable=false)
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Long userid;

	@Column(name="username")
	private String username;
	
	@Column(name="password")
	private String password;
	
	@Column(name="nickname")
	private String nickname;
	
	@Column(name="gender")
	private Short gender;
	
	@Column(name="email")
	private String email;
	
	@Column(name="avatar")
	private String avatar;

	@Column(name="birthday")
	@Temporal(TemporalType.DATE)
	private Date birthday;

	/*
	 * 0 不是VIP,普通用户
	 */
	@Column(name="vip_level")
	private Integer vipLevel;

	@Column(name="vip_time") 
	@Temporal(TemporalType.TIMESTAMP)
	private Date vipTime;

	@Column(name="login_cnt")
	private Integer loginCnt;

	@Column(name="encrypt_psd")
	private String encryptPsd;

	/**
	 * 主页地址，可以连接到其他网站的
	 */
	@Column(name="home_url")
	private String homeUrl;
	/**
	 * 1未锁
	 * 2锁定
	 * -1 永久锁定
	 */
	@Column(name="lock_status")
	private Short lockStatus;

	/**
	 * 锁定开始时间
	 */
	@Column(name="lock_start_time")
	@Temporal(TemporalType.TIMESTAMP)
	private Date lockStartTime;
	
	/**
	 * 锁定结束时间
	 */
	@Column(name="lock_end_time")
	@Temporal(TemporalType.TIMESTAMP)
	private Date lockEndTime;
	
	/**
	 * 锁定原因
	 */
	@Column(name="lock_sake")
	private String lockSake;
 
	/**
	 * 用户等级
	 */
	@Column(name="levels")
	private Integer levels;
	
	@Column(name="qq")
	private String qq;

	@Column(name="msn")
	private String msn;

	@Column(name="tel")
	private String tel;
	
	/**
	 * 使用键值对保存用户的个人配置信息;使用##(ConstantDB.USER_SETTING_SEP)分割不同的配置信息
	 * 例如 privacy_birthday=1##privacy_residence=1 参考constantDB.privacy_
	 */
	@Lob
	@Basic(fetch=FetchType.EAGER)
	@Column(name="setting")
	private String setting;
	
	/**
	 * 分析 setting的结果
	 */
	@Transient
	private Map<String, String> settingMap = null;
	
	/**
	 * 标记settring 是否被分析； 
	 */
	@Transient
	private boolean parsered = false;
	
	
	@Column(name="create_time")
	@Temporal(TemporalType.TIMESTAMP)
	private Date createTime;

	@Column(name="modify_time")
	@Temporal(TemporalType.TIMESTAMP)
	private Date modifyTime;
	
	@OneToOne(optional = true, cascade = CascadeType.ALL,fetch=FetchType.EAGER, mappedBy = "user")
	private Score score;
	
	@OneToOne(optional = true, cascade = CascadeType.ALL,fetch=FetchType.EAGER, mappedBy = "user")
	private Money money;
	
	@OneToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE},fetch=FetchType.LAZY, mappedBy="user")
	private Set<UserCases> caseses;
	
	@OneToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE},fetch=FetchType.LAZY, mappedBy="user")
	private Set<MoneyTransaction> moneyTrans;
	
	@OneToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE},fetch=FetchType.LAZY, mappedBy="user")
	private Set<ScoreTransaction> scoreTrans;
	
	@OneToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE},fetch=FetchType.LAZY, mappedBy="user")
	private Set<Convene> convenes;
	
	@Transient
	private UserProfile profile;
	/**
	 * 心情,从MOOD数据库获得最新的一条
	 */
	@Transient
	private String signature;
	
	public UserInfo() {
		super();
	}

	public Long getUserid() {
		return userid;
	}

	public void setUserid(Long userid) {
		this.userid = userid;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getNickname() {
		return nickname;
	}

	public void setNickname(String nickname) {
		this.nickname = nickname;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getSignature() {
		try{
			MoodManager mm = (MoodManager) ApplicationManager.appContext.getBean("moodManager");
			Mood mood = mm.getMoodByUserid(userid);
			signature = mood.getMood();
		}catch(Exception e){
			signature = "";
		}
		return signature;
	}

	public void setSignature(String signature) {
		this.signature = signature;
	}

	public Short getGender() {
		return gender;
	}

	public void setGender(Short gender) {
		this.gender = gender;
	}

	public Integer getVipLevel() {
		return vipLevel;
	}

	public void setVipLevel(Integer vipLevel) {
		this.vipLevel = vipLevel;
	}

	public Date getVipTime() {
		return vipTime;
	}

	public void setVipTime(Date vipTime) {
		this.vipTime = vipTime;
	}

	public Integer getLoginCnt() {
		return loginCnt;
	}

	public void setLoginCnt(Integer loginCnt) {
		this.loginCnt = loginCnt;
	}

	public String getAvatar() {
		return avatar;
	}

	public void setAvatar(String avatar) {
		this.avatar = avatar;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public String getEncryptPsd() {
		return encryptPsd;
	}

	public void setEncryptPsd(String encryptPsd) {
		this.encryptPsd = encryptPsd;
	}

	public Date getModifyTime() {
		return modifyTime;
	}

	public void setModifyTime(Date modifyTime) {
		this.modifyTime = modifyTime;
	}

	public String getHomeUrl() {
		return homeUrl;
	}

	public void setHomeUrl(String homeUrl) {
		this.homeUrl = homeUrl;
	}

	public Integer getLevels() {
		return levels;
	}

	public void setLevels(Integer levels) {
		this.levels = levels;
	}

	public Short getLockStatus() {
		return lockStatus;
	}

	public void setLockStatus(Short lockStatus) {
		this.lockStatus = lockStatus;
	}

	public String getLockSake() {
		return lockSake;
	}

	public void setLockSake(String lockSake) {
		this.lockSake = lockSake;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	public Date getLockStartTime() {
		return lockStartTime;
	}

	public void setLockStartTime(Date lockStartTime) {
		this.lockStartTime = lockStartTime;
	}

	public Date getLockEndTime() {
		return lockEndTime;
	}

	public void setLockEndTime(Date lockEndTime) {
		this.lockEndTime = lockEndTime;
	}

	public String getQq() {
		return qq;
	}

	public void setQq(String qq) {
		this.qq = qq;
	}

	public String getMsn() {
		return msn;
	}

	public void setMsn(String msn) {
		this.msn = msn;
	}

	public String getTel() {
		return tel;
	}

	public void setTel(String tel) {
		this.tel = tel;
	}

	public String getSetting() {
		return setting;
	}

	public void setSetting(String setting) {
		this.setting = setting;
	}

	public Score getScore() {
		return score;
	}

	public void setScore(Score score) {
		this.score = score;
	}

	public Money getMoney() {
		return money;
	}

	public void setMoney(Money money) {
		this.money = money;
	}

	public UserProfile getProfile() {
		return profile;
	}

	public void setProfile(UserProfile profile) {
		this.profile = profile;
	}

	public Set<MoneyTransaction> getMoneyTrans() {
		return moneyTrans;
	}

	public void setMoneyTrans(Set<MoneyTransaction> moneyTrans) {
		this.moneyTrans = moneyTrans;
	}

	public Set<ScoreTransaction> getScoreTrans() {
		return scoreTrans;
	}

	public void setScoreTrans(Set<ScoreTransaction> scoreTrans) {
		this.scoreTrans = scoreTrans;
	}

	public Set<UserCases> getCaseses() {
		return caseses;
	}

	public void setCaseses(Set<UserCases> caseses) {
		this.caseses = caseses;
	}

	public Set<Convene> getConvenes() {
		return convenes;
	}

	public void setConvenes(Set<Convene> convenes) {
		this.convenes = convenes;
	}

	public int getAge(){
		return DateUtil.getAge(birthday); 
	}
	
	/**
	 * 修改或者添加用户的个人设置
	 */
	public void addSetting(String key, String value){
		if(!parsered){
			getSettingMap();
		}
		settingMap.put(key, value);
		setting = formSetting();
	}
	/**
	 * 用户个人设置
	 */
	public Map<String, String> getSettingMap() {
		if(settingMap == null || settingMap.isEmpty()){
			settingMap = parserSetting();
		}
		return settingMap;
	}
	/**
	 * 用户个人设置
	 */
	public void setSettingMap(Map<String, String> settingMap) {
		this.settingMap = settingMap;
	}
	/**
	 * 用户个人设置
	 */
	public String getSettingValue(String key){
		if(!parsered){
			getSettingMap();
		}
		return settingMap.get(key);
	}
	/**
	 * 用户个人设置
	 */
	public Integer getIntegerSettingValue(String key){
		String value = getSettingValue(key);
		try{
			return Integer.valueOf(value);
		}catch(Exception e){
			return null;
		}
	}
	
	/**
	 * 用户个人设置
	 */
	
	private String formSetting(){
		StringBuffer buf = new StringBuffer();
		if(!settingMap.isEmpty()){
			for(Map.Entry<String, String> entry : settingMap.entrySet()){
				buf.append(entry.getKey())
				.append(ConstantDB.USER_SETTING_EQ)
				.append(entry.getValue())
				.append(ConstantDB.USER_SETTING_SEP);
			}
		}
		return buf.toString();
	}
	/**
	 * 用户个人设置
	 */
	private Map<String, String> parserSetting(){
		Map<String, String> map = new HashMap<String, String>();
		try{
			if(setting != null && !"".equals(setting)){
				String[] sets = setting.split(ConstantDB.USER_SETTING_SEP);
				String kv= null;
				String[] entry= null;
				String key= null;
				String value= null;
				for(int i =0; i<sets.length;i++){
					kv = sets[i];
					if("".equals(kv.trim())){
						continue;
					}
					entry = kv.split(ConstantDB.USER_SETTING_EQ);
					key= entry[0].trim();
					value = entry[1].trim();
					map.put(key, value);
				}
			}
		}catch(Exception e){}
		parsered = true;
		return map;
	}
	@Override
	public boolean equals(Object o) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public int hashCode() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return null;
	}
}
